﻿#include <iostream>
#include<vector>
#include<map>
#include<curl/curl.h>
#include<regex>
#include<filesystem>
using namespace std;

const static string URL = "http://127.0.0.1:9999/index.php";
const static string PATH = "./image";

size_t writeCallback(void* contents, size_t size, size_t nmemb, std::string* output) 
{
	size_t totalSize = size * nmemb;
	output->append((char*)contents, totalSize);
	return totalSize;
}

//编写一个发起请求的函数，接收返回函数
string request(const string& ulr,map<string,string>headers= map<string, string>())
{
	SetConsoleOutputCP(65001);
	CURL* curl;
	CURLcode statusCode;
	string htmlData;
	curl_global_init(CURL_GLOBAL_DEFAULT);
	curl = curl_easy_init();
	if (curl) {
		// 设置要抓取的⽹⻚地址
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
		//判断是否有cookies
		if (headers.find("cookies") != headers.end())
		{
			curl_easy_setopt(curl, CURLOPT_COOKIE, headers["cookies"].c_str());
		}
		
		curl_easy_setopt(curl, CURLOPT_URL, URL.c_str());
		// 设置回调函数，⽤于处理获取到的响应数据
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &htmlData);
		// 执⾏ HTTP 请求
		auto res = curl_easy_perform(curl);
		if (res != CURLE_OK)
		{
			std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
		}
		// 输出获取到的⽹⻚内容
		//cout << htmlData << std::endl;
		/*fstream out("html.txt");
		out << htmlData;
		out.close();*/
		//vector<string> vt = getTagsOfA(htmlData);
		/*for (int i = 0; i < vt.size(); ++i) {
		cout << vt[i] << endl;
		}*/
		// 清理 CURL 实例
		curl_easy_cleanup(curl);
	}
	else {
		std::cerr << "curl_easy_init() failed." << std::endl;
		return htmlData;
	}
	// 清理 libcurl
	curl_global_cleanup();

	return htmlData;
}

size_t write_callback(void* ptr, size_t size, size_t nmemb, void* stream) {
	return fwrite(ptr, size, nmemb, (FILE*)stream);
}
int download_file(const char* url, const char* output_filename) {
	CURL* curl = curl_easy_init();
	FILE* fp = fopen(output_filename, "wb"); // 打开⼀个⽂件⽤于保存下载的数据
	if (curl && fp) {
		// 设置下载选项
		curl_easy_setopt(curl, CURLOPT_URL, url);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
		// 执⾏下载请求
		CURLcode res = curl_easy_perform(curl);
		if (res != CURLE_OK) {
			fprintf(stderr, "下载失败: %s\n", curl_easy_strerror(res));
			fclose(fp);
			curl_easy_cleanup(curl);
			return -1;
		}
		fclose(fp);
	}
	else {
		fprintf(stderr, "初始化失败\n");
		if (fp) {
			fclose(fp);
		}
		if (curl) {
			curl_easy_cleanup(curl);
		}
		return -1;
	}
	curl_easy_cleanup(curl);
	return 0;
}

bool contains(vector<string>& vt, const string& value)
{
	return find(vt.begin(), vt.end(), value) != vt.end();
}

vector<map<string, string>> GetImagerUrl(const string& html)
{
	regex reg("/img/(\\w+)\\.(jpg|png)");
	auto end_it = sregex_iterator();
	vector<map<string, string>> vt;
	vector<string> v0;
	sregex_iterator it(html.begin(), html.end(), reg);
	smatch result;
	map<string ,string> URLMAP;
	for (; it != end_it; it++)
	{
		if (!contains(v0, it->str()))
		{

		}
		v0.push_back(it->str());
		result = *it;
		URLMAP["url"] = result[0].str();
		URLMAP["image_name"] = result[1].str() + "." + result[2].str();
		vt.push_back(URLMAP);
	}
	return vt;
}

int main()
{
	if (!filesystem::exists(PATH))
	{
		filesystem::create_directories(PATH);
	}
	map<string, string>headers;
	headers["cookies"] = "PHPSESSID=rl37nbtc6857cddpb8na7qn2sf";
	string html;
	html = request("http://127.0.0.1:9999", headers);
	cout << html << "\n";
	vector<map<string, string>> vt = GetImagerUrl(html);
	for (auto& w : vt)
	{
		for (auto& u : w)
		{
			cout << u.first << "    " << u.second << "\n";
		}
	
	map<string,string> urlmap;
	string url;
	string image_name;

	while (!vt.empty())
	{
		urlmap = vt.back();
		vt.pop_back();
		url=URL+"/"+urlmap["url"];
		image_name=PATH+"/"+urlmap["image_name"];
		const char* file_url = url.c_str();
		const char* fule_name = image_name.c_str();
		download_file(file_url, fule_name);
	}

}

